#! -*- coding: utf-8 -*-

"""
Baan xmlrpc server
"""

from SimpleXMLRPCServer import SimpleXMLRPCServer
import xmlrpclib
import baan_stpapi
import SocketServer
from threading import Lock
import time

class BaanXMLRPCServer(SimpleXMLRPCServer):
    def __init__(self,addr=("", 8000),logRequests=False,multithread=False):
        SimpleXMLRPCServer.__init__(self,addr,logRequests=logRequests,allow_none=True)
        self.timeout = 10
        self.multithread = multithread
        self.dispatch = BaanDispatch(self)
        self.register_instance(self.dispatch)
        self.clients = []
        self.lock = Lock()

    def register_instance(self,instance):
        SimpleXMLRPCServer.register_instance(self,instance)

    def create_clients(self):
        #start one instane for each class string found
        for func in self.dispatch.funcs.values():
            self.clients.append(func._connect())

    def serve_forever(self):
        self.create_clients()
        try:
            SimpleXMLRPCServer.serve_forever(self)
        except:
            pass
        finally:
            self.close_all_clients()

    def shutdown(self):
        SimpleXMLRPCServer.shutdown()


    def close_all_clients(self):
        SimpleXMLRPCServer.server_close(self)
        for client in self.clients:
            client.quit()
        self.clients = []

    def addFunctions(self,baanfunc_instance):
        baanfunc_instance.multithread = self.multithread
        self.dispatch._add_funcs(baanfunc_instance.name,baanfunc_instance)



class AsyncBaanXMLRPCServer(SocketServer.ThreadingMixIn,BaanXMLRPCServer):
    def __init__(self,addr=("", 8000),logRequests=False):
        BaanXMLRPCServer.__init__(self,addr,logRequests=logRequests,multithread=True)

class BaanDispatch(object):
    def __init__(self,server):
        self.server = server
        self.funcs = {}

    def _add_funcs(self,group_name,baanfunc_instance):
        self.funcs[group_name] = baanfunc_instance

    def _listMethods(self):
        methods = ['test']
        for name,funcs in self.funcs.items():
            methods += funcs._listMethods()
        return methods

    def _dispatch(self,method,params):
        result = None
        with self.server.lock:
            methd = method.split('.',1)
            if len(methd) == 1:
                func = getattr(self,method)
                result = func(*params)
            else:
                funcs = self.funcs.get(methd[0])
                result = funcs._dispatch(methd[1],params)
        return result

    def test(self):
        return 'ok'

class BaanFunc(object):
    def __init__(self,name,class_string='Baan4.Application'):
        self.name = name
        self.class_string = class_string
        self.multithread = False
        #self._connect()

    def _listMethods(self):
        methods = dir(self)
        def mfilter(m):
            #print type(getattr(self,m))
            return m[0] != '_'
        methods = filter(mfilter,methods)
        def addname(m):
            return self.name+'.'+m
        methods = map(addname,methods)
        return methods

    def _connect(self):
        self.client = baan_stpapi.Baan(self.class_string,self.multithread)
        return self.client

    def _disconnect(self):
        try:
            self.client.quit()
        except:
            pass

    def _dispatch(self, method, params):
        if method[0] == '_':
            raise Exception('method "%s" is not supported' % method)
        func = getattr(self,method)
        res = func(self.client,*params)
        return res

    def testwait(self,client,seconds=2):
        time.sleep(seconds)

    def test(self,client):
        return client.get_company()

    def get_company(self,client,company_number):
        client.switch_to_company(company_number)
        return client.get_company()


if __name__ == '__main__':
    # Create server
    server = BaanXMLRPCServer(logRequests=True)
    #server = AsyncBaanXMLRPCServer(logRequests=True)
    server.addFunctions(BaanFunc('baantest'))
    server.register_introspection_functions()

    # Run the server's main loop
    print 'Lancement du serveur XML-RPC.'
    server.serve_forever()


